﻿/*
 * PsTFS is a set of PowerShell commands to manage and use Team Foundation Server. PowerShell 
 * effectiveness is combined with the power of TFS API to maximizes TFS capabilities.
 * 
 * Creator : Choulant Noham
 * Mail : choulant@gmail.com
 * Blog : http://choulant.blogspot.com
 * 
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.TeamFoundation.Server;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.VersionControl.Common;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using Microsoft.TeamFoundation.Build.Client;

namespace PowerShell.Host.PsTFS.CdmLet.PsObject
{
    /// <summary>
    /// Classe de service permettant de retourner les service de Team Foundation Server
    /// </summary>
    public class PsService
    {
        /// <summary>
        /// Utilisateur en cours authentifier sur le serveur TFS
        /// </summary>
        public static string User = string.Empty;
        /// <summary>
        /// Objet contenant le Version Control Server
        /// </summary>
        private static VersionControlServer vcs = null;
        /// <summary>
        /// Objet contenant le WorkItem Store
        /// </summary>
        private static WorkItemStore wis = null;

        /// <summary>
        /// Objet contenant le IGroupe Security Service
        /// </summary>
        private static IGroupSecurityService gss = null;

        /// <summary>
        /// Objet contenant le IGroupe Security Service
        /// </summary>
        private static ICommonStructureService css = null;

        #region IGroupSecurityService

        /// <summary>
        /// Methode retournant le IGroupeSecurityService qui permet de travailer sur la gestion de la sécurité de TFS
        /// </summary>
        /// <param name="Tfs"></param>
        /// <returns></returns>
        public static IGroupSecurityService IGSS(TeamFoundationServer Tfs)
        {
            gss = (IGroupSecurityService)Tfs.GetService(typeof(IGroupSecurityService));
            
            return gss;
        }

        #endregion IGroupSecurityService


        public static ICommonStructureService ICSS(TeamFoundationServer Tfs)
        {
            css = (ICommonStructureService)Tfs.GetService(typeof(ICommonStructureService));

            return css;
        }

        #region VersionControlServer

        public static VersionControlServer VCS()
        {
            if (vcs == null)
            {
                if (wis != null)
                {
                    VCS(wis.TeamFoundationServer);
                }
            }
            return vcs;
        }
        /// <summary>
        /// Permet de récupérer le version contrôle server et de rendre générique la gestion des events
        /// </summary>
        /// <param name="Tfs">Serveur TFS</param>
        /// <returns>Le version control Server</returns>
        public static VersionControlServer VCS(TeamFoundationServer Tfs)
        {
            if (vcs != null)
            {
                if (vcs.TeamFoundationServer.Name != Tfs.Name)
                {
                    vcs = null;
                }
            }
            if (vcs == null)
            {
                vcs = (VersionControlServer)Tfs.GetService(typeof(VersionControlServer));
                vcs.AfterWorkItemsUpdated += new AfterWorkItemsUpdatedEventHandler(vcs_AfterWorkItemsUpdated);
                vcs.BeforeCheckinPendingChange += new ProcessingChangeEventHandler(vcs_BeforeCheckinPendingChange);
                vcs.BeforeWorkItemsUpdate += new BeforeWorkItemsUpdateEventHandler(vcs_BeforeWorkItemsUpdate);
                vcs.Conflict += new ConflictEventHandler(vcs_Conflict);
                vcs.NonFatalError += new ExceptionEventHandler(vcs_NonFatalError);
                vcs.NewPendingChange += new PendingChangeEventHandler(vcs_NewPendingChange);
                vcs.Getting += new GettingEventHandler(vcs_Getting);

                PsService.User = vcs.TeamFoundationServer.AuthenticatedUserName;
            }

            return vcs;
        }

        static void vcs_Getting(object sender, GettingEventArgs e)
        {
           PsLog.AddLog(e,"Getting: " + e.TargetLocalItem + ", status: " + e.Status);
        }

        static void vcs_NewPendingChange(object sender, PendingChangeEventArgs e)
        {
            PsLog.AddLog(e, "Pending " + PendingChange.GetLocalizedStringForChangeType(e.PendingChange.ChangeType) +
                              " on " + e.PendingChange.LocalItem);
        }

        static void vcs_NonFatalError(object sender, ExceptionEventArgs e)
        {
            if (e.Exception != null)
            {
                PsLog.AddLog(e, "Non-fatal exception: " + e.Exception.Message);
            }
            else
            {
                PsLog.AddLog(e, "Non-fatal failure: " + e.Failure.Message);
            }
        }

        static void vcs_Conflict(object sender, ConflictEventArgs e)
        {
            PsLog.AddLog(e, "Conflict : " + e.Message);
        }

        static void vcs_BeforeWorkItemsUpdate(object sender, WorkItemsUpdateEventArgs e)
        {
            foreach (WorkItemCheckinInfo wci in e.WorkItemInfo)
            {
                PsLog.AddLog(e, "AfterWorkItemsUpdated : " + wci.WorkItem.Title + "| CheckinAction : " + wci.CheckinAction.ToString());
            }
        }

        static void vcs_BeforeCheckinPendingChange(object sender, ProcessingChangeEventArgs e)
        {
            PsLog.AddLog(e, "BeforeCheckinPendingChange : " + e.PendingChange.LocalItem);
        }

        static void vcs_AfterWorkItemsUpdated(object sender, WorkItemsUpdateEventArgs e)
        {
            foreach (WorkItemCheckinInfo wci in e.WorkItemInfo)
            {
                PsLog.AddLog(e, "AfterWorkItemsUpdated : " + wci.WorkItem.Title + "| CheckinAction : " + wci.CheckinAction.ToString());
            }
        }

        #endregion VersionControlServer

        #region WorkItemStore

        /// <summary>
        /// Methode retournant le WorkItem Store
        /// </summary>
        /// <returns></returns>
        public static WorkItemStore WIS()
        {
            if (wis == null)
            {
                if ( vcs != null)
                {
                    WIS(vcs.TeamFoundationServer);
                }
            }
            return wis;
        }
        /// <summary>
        /// Objet retournant le workitem store avec un TFS précisé
        /// </summary>
        /// <param name="Tfs">Serveur TFS</param>
        /// <returns></returns>
        public static WorkItemStore WIS(TeamFoundationServer Tfs)
        {
            if (wis != null)
            {
                if (wis.TeamFoundationServer.Name != Tfs.Name)
                {
                    wis = null;
                }
            }

            if (wis == null)
            {

                wis = (WorkItemStore)Tfs.GetService(typeof(WorkItemStore));

                wis.MetadataChanged += new MetadataChangeEventHandler(wis_MetadataChanged);
                wis.ImportEventHandler += new ImportEventHandler(wis_ImportEventHandler);
            }
                
            return wis;
            
        }

        internal static void wis_ImportEventHandler(object sender, ImportEventArgs e)
        {
            PsLog.AddLog(e,((WorkItemStore)sender).ToString() + " : " + e.Message);
        }

        static void wis_MetadataChanging(object sender, MetadataEventArgs e)
        {
            PsLog.AddLog(e, e.MetadataChangeFlags.ToString());
        }

        static void wis_MetadataChanged(object sender, MetadataEventArgs e)
        {
            PsLog.AddLog(e, e.MetadataChangeFlags.ToString());
        }

        #endregion WorkItemStore

        public static IBuildServer IBS(TeamFoundationServer Tfs)
        {
            IBuildServer ibs = (IBuildServer)Tfs.GetService(typeof(IBuildServer));
            return ibs;
        }
    }
}
